package de.fhwf.mixedreality.client2007;

import java.util.StringTokenizer;

import de.fhwf.mixedreality.client.IClient;
import de.fhwf.mixedreality.client.Vector;

class MessageParser { 
 private PositionsStorage mPositions;
 
 private boolean mOpponentUpdated[];
 private boolean mTeammateUpdated[];
 private int mMyID;
 private boolean mIAmLost;
 private double mTime;
 private boolean mGameIsOn;
 private int mGoals[];

 public MessageParser(PositionsStorage positions) {
  mPositions = positions;
  mOpponentUpdated = new boolean[IClient.MAX_PLAYERS];
  mTeammateUpdated = new boolean[IClient.MAX_PLAYERS];
  mGoals = new int[2];
 }
 
 void parse(String data) {
  String s;

  // We suppose we are not lost
  mIAmLost = false;

  // Initialize update checklist
  for (int i = 0; i < IClient.MAX_PLAYERS; i++) {
   mOpponentUpdated[i] = false;
   mTeammateUpdated[i] = false;
  }

  // Loop through the lines
  StringTokenizer st = new StringTokenizer(data, "\n");
  while (st.hasMoreTokens()) {
   String line = st.nextToken();
   String parameter = getParameter(line);
  
   if (parameter.equals("myid")) {
    // Own id
    s = getValueString(line, "myid ");
    mMyID = Integer.parseInt(s);
   } else if (parameter.equals("time")) {
    // Time
    s = getValueString(line, "time ");
    mTime = Double.parseDouble(s);
   } else if (parameter.equals("game")) {
    // Game state
    s = getValueString(line, "game ");
    if (s.equals("on")) {
     mGameIsOn = true;
    } else if (s.equals("off")) {
     mGameIsOn = false;
    }
   } else if (parameter.equals("goals")) {
    // Scores
    s = getValueString(line, "goals ");
    String parts[] = s.split(" ", 2);
    if (parts.length >= 2) {
     mGoals[0] = Integer.parseInt(parts[0]);
     mGoals[1] = Integer.parseInt(parts[1]);
    }
   } else if (parameter.equals("lost")) {
    // Is lost?
    if (line.startsWith("lost")) {
     // Oops, too bad...
     mIAmLost = true;
     // Nothing else to be done then, I guess...
     break;
    }
   } else if (parameter.equals("ball")) {
    // Ball
    s = getValueString(line, "ball ");
    mPositions.setBallPos(Vector.parseVector(s));
   } else if (parameter.equals("op")) {
    // Opponent
    s = getValueString(line, "op ");
    String parts[] = s.split(" ", 2);
    if (parts.length >= 2) {
     int i = Integer.parseInt(parts[0]);
     if (i >= 0 && i < IClient.MAX_PLAYERS) {
      mOpponentUpdated[i] = true;
      mPositions.setOpponentPos(i, Vector.parseVector(parts[1]), 0);
     }
    }
   } else if (parameter.equals("tm")) {
    // Teammate
    s = getValueString(line, "tm ");
    String parts[] = s.split(" ", 2);
    if (parts.length >= 2) {
     int i = Integer.parseInt(parts[0]);
     if (i >= 0 && i < IClient.MAX_PLAYERS) {
      mTeammateUpdated[i] = true;
      mPositions.setTeammatePos(i, Vector.parseVector(parts[1]), 0);
     }
    }
   } else if (parameter.equals("mygoal")) {
    // My Goal
    s = getValueString(line, "mygoal ");
    Vector v[] = Vector.parseDoubleVector(s);
    mPositions.setMyGoalPole1(v[0]);
    mPositions.setMyGoalPole2(v[1]);
   } else if (parameter.equals("opgoal")) {
    // Opponent Goal
    s = getValueString(line,"opgoal ");
    Vector v[] = Vector.parseDoubleVector(s);
    mPositions.setOpGoalPole1(v[0]);
    mPositions.setOpGoalPole2(v[1]);
   } else if (parameter.equals("mycorners")) {
    // My Corners
    s = getValueString(line,"mycorners ");
    Vector v[] = Vector.parseDoubleVector(s);
    mPositions.setMyCornerFlag1(v[0]);
    mPositions.setMyCornerFlag2(v[1]);
   } else if (parameter.equals("opcorners")) {
    // Opponent Corners
    s = getValueString(line,"opcorners ");
    Vector v[] = Vector.parseDoubleVector(s);
    mPositions.setOpCornerFlag1(v[0]);
    mPositions.setOpCornerFlag2(v[1]);
   }
  }
 }

 double getTime() {
  return mTime;
 }
 
 boolean isGameOn() {
  return mGameIsOn;
 }
 
 int getMyID() {
  return mMyID;
 }

 int getTeamGoals() {
  return mGoals[0];
 }

 int getOpponentGoals() {
  return mGoals[1];
 }
 
 boolean isLost() {
  return mIAmLost;
 }
 
 // Tells if a given opponent's position was updated from last message
 boolean getOpponentUpdateState(int i) {
  if (i >= 0 && i < IClient.MAX_PLAYERS) {
   return mOpponentUpdated[i];
  }
  return false;
 }

 // Tells if a given teammate's position was updated from last message
 boolean getTeammateUpdateState(int i) {
  if (i >= 0 && i < IClient.MAX_PLAYERS) {
   return mTeammateUpdated[i];
  }
  return false;
 } 

 /* Returns the parameters associated with
  * a flag in the data received from the server.
  * (e.g. returns "21.5 3.4" from "ball 21.5 3.4")
  * if given the flag "ball ".
  */ 
 private String getValueString(String dataLine, String flag) {
  int loc = dataLine.indexOf(flag, 0);
  if ( loc > -1) {
   return dataLine.substring(loc + flag.length());
  } else {
	  System.out.println("No Values found, returning space");
   return "";
  }
 } 
 
 private String getParameter(String dataLine) {
  int loc = dataLine.indexOf(" ", 0);
  if (loc > -1) {
   return dataLine.substring(0, loc);
  } else {
   return dataLine;
  }
 }
}